#include <gfx/Map.h>
#include <algorithm>

using namespace gfx;

Map::Map(const int& w, const int& h) : vMap(w,vRow(h,0))
{
}

Map::Map(const vMap& map) :  vMap(map)
{
}

Map::~Map(void)
{

}


vMap Map::getSubMap(const sf::IntRect& zone) const
{
	vMap map;

	//Redimensionne la zone pour eviter les debordemments (access out of range)
	sf::IntRect tZone = fit(zone);

	//Copie la zone dans un autre vector en y allant colonne par colonne
	for(const_iterator x=begin()+tZone.Left;x!=(begin()+tZone.Right);x++)
	{
			vRow row(tZone.GetHeight());
			row.assign((*x).begin()+tZone.Top,(*x).begin()+tZone.Bottom);
			map.push_back(row);
	}

	return map;
}

void Map::setSubMap(const sf::IntRect& zone, const vMap& map)
{
	sf::IntRect tZone = fit(zone);

	for(int i=0;i<tZone.GetWidth();i++)
		copy(map[i].begin(), map[i].begin()+tZone.GetHeight(), at(i+tZone.Left).begin()+tZone.Top);

}

void Map::setSubMap(const sf::IntRect& zone, int val)
{
	sf::IntRect tZone = fit(zone);

	for(int i=tZone.Left;i<tZone.Right;i++)
		fill(at(i).begin()+tZone.Top, at(i).begin()+tZone.Bottom, val);

}



int Map::getWidth() const
{
	return (int)size();
}

int Map::getHeight() const
{
	if(size())
		return (int)(*this)[0].size();
	return 0;
}

sf::IntRect Map::fit(const sf::IntRect& zone) const
{
	sf::IntRect tZone(zone);

	if((int)size()<tZone.Right)
		tZone.Right=(int)size();
	if(tZone.Left<0)
		tZone.Left=0;
	if((int)size() && (int)(*this)[0].size()<tZone.Bottom)
		tZone.Bottom=(int)(*this)[0].size();
	if(tZone.Top<0)
		tZone.Top=0;

	return tZone;
}

